Play framework 2.0でJSONPを使う
JSONPとは?
JSONPとは、HTMLのscriptタグを使用してクロスドメインなデータを取得する仕組みです。 JSONでデータをやりとりする場合、通常は同一以外と通信することはできません。 しかし、HTMLのscriptタグのsrcに別ドメインのURLを指定して通信できる点を利用し、別ドメインのサーバからデータを取得することが可能になります。
JSONPではレスポンスの内容がjavascript関数呼び出しの形式となります。 そのため、src属性に指定するURLにその関数の名前をクエリ文字列として加えます。
<script type='text/javascript' src='http://anotherDomain.com/getData?callback=foo'>
そしてレスポンスとして、下記のようなJSON形式のデータを引数とする関数の呼び出し文が返されます。
foo({"name":"syuta","age":30})
JSONPでレスポンスを受け取る
Playframework 2.0では最初からJSONをサポートしていますが、JSONPについては独自で実装する必要がありました。 しかし、現時点のHEADではJSONPのためのヘルパクラスが実装されているようなので、その紹介をします。
今回使用した動作環境は以下のとおりです。 現状リリースされているPlayframewor2.0ではJSONPのサポートが実装されていないため、HEADを取得してビルドします
- OS : MacOS X 10.7.3
- Playframework : HEAD
- Java : 1.6.0_26
注意: この記事ではgithubから取得したHEAD版を使用して試しています。 正式リリース前の状況のため思わぬ不具合が生じるかもしれませんので、ご了承ください。
ソースのHEADを取得してセットアップ
まだgithubからソースを取得していない人は、play2.0のソースを取得してビルドしましょう。
$ git clone https://github.com/playframework/Play20.git $ cd Play20/framework $ ./build > complile > build-repository > publish-local
すでにソースを取得している人は、最新の状態に更新してビルドします。
$ git pull $ cd Play20/framework $ ./cleanEverything $ ./build > compile > build-repository > publish-local
これで準備ができました。
プロジェクト作成
Scalaベースのプロジェクトを作成し、sbtコンソールを起動します。
% play new jsonp % cd jsonp % play
ソースをEclipseで編集したいなら、eclipsifyを実行してeclipseプロジェクト化してインポートしてソースの修正をしましょう。
>[jsonp] $ eclipsify
サンプルコードを記述
今回はlocalhost:9000にアクセスしたらJSONPで通信を行い、結果をログに表示するだけの簡単なサンプルを作成します。 まずはデフォルトのコントローラを修正します。
package controllers import play.api._ import play.api.mvc._ import play.api.libs.json._ import play.api.libs.json.Json._ import play.api.libs.Jsonp object Application extends Controller { def index = Action { Ok(views.html.index("Your new application is ready.")) } def jsonpService(callback:String) = Action { val json = JsObject(List("foo" -> JsString("bar"))) Ok(Jsonp(callback, json)) } }
jsonpServiceメソッドでは、callbackパラメータを受け取ります。 そしてJSONデータを生成し、 JSONPクラスでラップして返します。 このメソッドをroutesファイルで指定しましょう。
GET /jsonp-service controllers.Application.jsonpService(callback: String)
コントローラができたら、index.scala.htmlを修正します。 アクセス時にjQueryを使用してJSONP通信をするようにしてみましょう。
@(message: String) @main("JSONP in Play 2.0") { <script type="text/javascript"> $(function() { $.ajax({ url: "http://localhost:9000/jsonp-service", dataType: "jsonp", success:function(json){ console.dir(json); }, error:function(){ alert('error'); } }); }); </script> Hello! }
これでアクセスすると、取得したJSONPデータがログに表示されます。 今回は同一ドメイン上で動作確認しましたが、別ドメインでも問題なく動作します。
まとめ
今回はPlayframework 2.0でのJSONP通信方法についてご紹介しました。 この機能はリリースされているバージョン(2.0)には入っていませんが、次のバージョンでは使用できるようになると思います。